﻿using System.Web.Mvc;
using System.Web;
using System.Web.UI.WebControls;
using System.Web.SessionState;
using thailandProject.Models;
using System;

namespace MvcFilters.Infrastructure.Filters
{
    public class ThailandAuthorize : AuthorizeAttribute
    {
        private int permissionLevel;
        private int[] whitelist_userIDs; //When not null, only IDs contained within can access the function
        private int[] blacklist_userIDs; //When not null, IDs contained within cannot access the function (has priority over whitelist)

        public ThailandAuthorize(int permissionLevel = 2)
        {
            try
            {
                this.permissionLevel = permissionLevel;
            }
            catch (Exception ex)
            {
                ErrorLog.logError(ex);
            }
        }

        public ThailandAuthorize(int permissionLevel, int[] whitelist)
        {
            try
            {
                this.permissionLevel = permissionLevel;
                this.whitelist_userIDs = whitelist;
            }
            catch (Exception ex)
            {
                ErrorLog.logError(ex);
            }
        }

        public ThailandAuthorize(int permissionLevel, int[] whitelist, int[] blacklist)
        {
            try
            {
                this.permissionLevel = permissionLevel;
                this.whitelist_userIDs = whitelist;
                this.blacklist_userIDs = blacklist;
            }
            catch (Exception ex)
            {
                ErrorLog.logError(ex);
            }
        }

        protected override void HandleUnauthorizedRequest(AuthorizationContext context)
        {
            try
            {
                HttpSessionStateWrapper Session = new HttpSessionStateWrapper(HttpContext.Current.Session);
                HttpResponseWrapper Response = new HttpResponseWrapper(HttpContext.Current.Response);
                HttpRequestWrapper Request = new HttpRequestWrapper(HttpContext.Current.Request);

                if (thailandProject.Controllers.AccountController.AuthenticateUser(Session, Response, Request))
                {
                    //Check to see if the user is of type roleType
                    int up = (int)Session["userPerm"];
                    USER user = (USER)Session["user"];

                    if (blacklist_userIDs != null)
                    {
                        for (int i = 0; i < blacklist_userIDs.Length; i++)
                        {
                            if (blacklist_userIDs[i] == user.userID)
                            {
                                failContextResult(context, Request);
                                return;
                            }
                        }
                    }//if the blacklist exists

                    if (up <= permissionLevel)
                    {
                        //If the user's permissionLevel is acceptable
                        if (whitelist_userIDs != null)
                        {
                            //If list requires a whitelist, see if the user exists on it
                            for (int i = 0; i < whitelist_userIDs.Length; i++)
                                if (whitelist_userIDs[i] == user.userID)
                                    return;

                            //If the user wasn't found on the list, fail the authentication
                            failContextResult(context, Request);
                            return;
                        }
                        else //If the whitelist doesn't exist, pass the authentication
                        {
                            return;
                        }
                    }//End to permID acceptable

                    failContextResult(context, Request);
                }//End to if the user is logged in
                else
                {
                    string url = Request.Url.AbsoluteUri;
                    string[] sections = url.Split('/');
                    //http:
                    // (empty)
                    // hostname:port
                    // Controller
                    //Anything after this means it is not the root directory, so add a ../

                    string padding = (sections.Length > 4 ? "../" : "");

                    context.Result = new RedirectResult(padding + "Account/LogOn");
                }
            }
            catch (Exception ex)
            {
                ErrorLog.logError(ex);
            }
        }

        public void failContextResult(AuthorizationContext context, HttpRequestWrapper Request)
        {
            try
            {
                string url = Request.Url.AbsoluteUri;
                string[] sections = url.Split('/');
                //http:
                // (empty)
                // hostname:port
                // Controller
                //Anything after this means it is not the root directory, so add a ../

                string padding = (sections.Length > 4 ? "../" : "");

                context.Result = new RedirectResult(padding + "Account/Unauthorized");
            }
            catch (Exception ex)
            {
                ErrorLog.logError(ex);
            }
        }
    }
}